package qj.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;

/**
 * 
 * @author QuanLA
 */
public class DebugUtil4 {
	
	public static void storing() {
		HashMap cache = loadCache();
		for (Iterator iter = cache.keySet().iterator(); iter.hasNext();) {
			String ele = (String) iter.next();
			System.out.println(ele);
		}
	}
	
	public static void store(String key, Object value) {
		HashMap cache = loadCache();
		if (cache == null)
			cache = new HashMap();
		cache.put(key, value);
		storeCache(cache);
		System.out.println("DebugUtil: [" + key + "] was successfully stored");
	}
	
	private static void storeCache(HashMap cache) {
		File file = new File("C:/temp/quanjava_debugutil_cache.dat");
		FileUtil4.mkParentDirs(file);
		ObjectOutputStream oo = null;
		FileOutputStream fo = null;
		try {
			fo = new FileOutputStream(file);
			oo = new ObjectOutputStream(
					fo);
			oo.writeObject(cache);
			oo.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (oo!=null)
					oo.close();
				if (fo!=null)
					fo.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}		
		
	}

	private static HashMap loadCache() {
		File file = new File("C:/temp/quanjava_debugutil_cache.dat");
		ObjectInputStream oi = null;
		Object o = null;
		try {
			oi = new ObjectInputStream(new FileInputStream(file));
			o = oi.readObject();
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				if (oi!=null)
					oi.close();
			} catch (IOException e) {
			}
		}
		return (HashMap) o;
	}

	public static Object load(String key) {
		return load(key, null);
	}

	public static Object load(String key, Object defaultValue) {
		System.out.println("DebugUtil: [" + key + "] was successfully loaded");
		Object object = loadCache().get(key);
		if (object != null) {
			return object;
		} else {
			return defaultValue;
		}
	}
//
//	/**
//	 * 
//	 * @param map
//	 */
//	public static void debug(Map map) {
//		
//		Iterator entries = map.entrySet().iterator();
//		while (entries.hasNext()) {
//			Entry entry = (Entry) entries.next();
//			System.out.println("[" + entry.getKey() + "]:\t[" + entry.getValue() + "]");
//		}
//	}

	/**
	 * Make a string to show array values
	 * 
	 * @param arr -
	 *            The array to be shown
	 * @return String which shows all array values
	 */
	public static String debug(int[] arr) {
		StringBuffer sb = new StringBuffer("{");
		for (int i = 0; i < arr.length; i++) {
			if (i > 0)
				sb.append(", ");
			sb.append(arr[i]);
		}
		sb.append("}");

		String result = sb.toString();
		System.out.println(result);
		return result;
	}

	/**
	 * Make a string to show array values
	 * 
	 * @param arr -
	 *            The array to be shown
	 * @return String which shows all array values
	 */
	public static String debug(Object[] arr) {
		StringBuffer sb = new StringBuffer("{");
		for (int i = 0; i < arr.length; i++) {
			if (i > 0)
				sb.append(", ");
			sb.append(arr[i]);
		}
		sb.append("}");

		String result = sb.toString();
		System.out.println(result);
		return result;
	}
	
	/**
	 * Make a string to show array values
	 * 
	 * @param arr -
	 *            The array to be shown
	 * @return String which shows all array values
	 */
	public static String debugln(Object[] arr) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < arr.length; i++) {
			if (i > 0)
				sb.append("\n");
			sb.append(arr[i]);
		}

		String result = sb.toString();
		System.out.println(result);
		return result;
	}

	/**
	 * 
	 * @param col
	 */
	public static String debug(Collection col) {
		StringBuffer sb = new StringBuffer("{");
		int i = 0;
		for (Iterator iter = col.iterator(); iter.hasNext();) {
			if (i > 0)
				sb.append(", ");
			sb.append(iter.next());
			i++;
		}
		sb.append("}");

		String result = sb.toString();
		System.out.println(result);
		return result;
	}


	/**
	 * 
	 * @param col
	 */
	public static void debugln(Collection col) {
		for (Iterator iter = col.iterator(); iter.hasNext();) {
			System.out.println(iter.next());
		}
	}
	
	public static String debug(ResultSet rs) throws SQLException {
		if (rs==null) {
			System.out.println("null");
			return "null";
		}
			
		StringBuffer sb = new StringBuffer();
		
		ResultSetMetaData meta = rs.getMetaData();
		
		int columnCount = meta.getColumnCount();
		
		// Write header row
		for (int i=1;i<=columnCount;i++) {
			if (i > 1)
				sb.append(", ");
			sb.append(meta.getColumnLabel(i));
		}
		sb.append("\n");

		// Write records
		int count = 0;
		while (rs.next()) {
			
			for (int i=1;i<=columnCount;i++) {
				if (i > 1)
					sb.append(", ");
				if (meta.getColumnType(i)!=Types.BLOB) {
					sb.append(rs.getString(i));
				} else {
					sb.append(" (( BLOB )) ");
				}
			}

			count++;
			sb.append("\n");
		}

		String result = "Retrieved " + count + " rows:\n" + sb.toString();
		System.out.println(result);
		return result;
	}
	

	public static String debug(int[][] arr) {
		StringBuffer sb = new StringBuffer("{");
		for (int i = 0; i < arr.length; i++) {
			if (i > 0)
				sb.append(", ");

			sb.append("{");
			for (int j = 0; j < arr[i].length; j++) {
				if (j > 0)
					sb.append(", ");
				sb.append(arr[i][j]);
			}
			sb.append("}");
		}
		sb.append("}");

		String result = sb.toString();
		System.out.println(result);
		return result;
	}

	public static String debug(byte[] bytes) {
		StringBuffer sb = new StringBuffer();
		sb.append("{");
		for (int i = 0; i < bytes.length; i++) {
			if (i > 0)
				sb.append(", ");
			sb.append(bytes[i]);
		}
		sb.append("}");

		String result = sb.toString();
		System.out.println(result);
		return result;
	}
	
	public static String debug(double[] data) {
		StringBuffer sb = new StringBuffer();
		sb.append("{");
		for (int i = 0; i < data.length; i++) {
			if (i > 0)
				sb.append(", ");
			sb.append(data[i]);
		}
		sb.append("}");

		String result = sb.toString();
		System.out.println(result);
		return result;
	}
//	public static String debug(byte[] bytes) {
//		String string = new String(bytes);
//		System.out.println(string);
//		return string;
//	}

	public static String debug(Reader r) {
		StringBuffer sb = new StringBuffer();
		sb.append("{");
		int i;
		try {
			while ((i = r.read()) != -1)
				sb.append(i + ", ");
		} catch (IOException e) {
		}
		sb.append("}");

		String result = sb.toString();
		System.out.println(result);
		return result;
	}

	public static String debug(Matcher m) {
		StringBuffer sb = new StringBuffer();
		sb.append("{");
		int groupCount = m.groupCount();
		for (int i = 1; i <= groupCount; i++) {
			sb.append(i).append("=").append(m.group(i)).append(", ");
		}
		sb.append(0).append("=").append(m.group(0)).append("}");
		
		String result = sb.toString();
		System.out.println(result);
		return result;
	}
	
	/**
	 * Debug bean contents
	 * @param bean
	 */
	public static String debug(Object bean) {
		if (bean == null) {
			System.out.println(bean);
			return "null";
		}
		
		// Check if this bean support toString? return o.toString(): continue
		try {
			if (! (bean.getClass().getMethod("toString", (Class[]) null).getDeclaringClass() == Object.class)) {

				System.out.println(bean.toString());
				return bean.toString();
			}
		} catch (SecurityException e) { // Never
		} catch (NoSuchMethodException e) { // Never
		}
		
		// Build String
		StringBuffer sb = new StringBuffer();
		// Get all getters' methods
		sb.append("{");
		List getters = BeanUtil4.getGetters(bean);
		for (int i = 0; i < getters.size(); i++) {
			if (i > 0)
				sb.append(", ");
			
			Method method = (Method) getters.get(i);
			try {
				sb.append(StringUtil4.lowerCaseFirstChar(method.getName().substring(3))).append("=");
				sb.append(method.invoke(bean, (Object[]) null));
			} catch (IllegalArgumentException e) {
			} catch (IllegalAccessException e) {
			} catch (InvocationTargetException e) {
			}
		}
		sb.append("}");
		
		System.out.println(sb);
		
		return sb.toString();
	}

	public static void debugln(Map map) {
		Iterator keys = map.keySet().iterator();
		while (keys.hasNext()) {
			Object key = keys.next();
			System.out.println(key + "=" + map.get(key));
		}
	}

	public static void debug(int i) {
		System.out.println(i);
	}

	public static String debugClasses(Object[] args) {
		StringBuffer sb = new StringBuffer("{");

		for (int i = 0; i < args.length; i++) {
			if (i > 0)
				sb.append(", ");
			sb.append(args[i].getClass().getName());
		}

		sb.append("}");
		return sb.toString();
	}

//	/**
//	 * 
//	 * @param dic
//	 */
//	public static void debugln(Dictionary dic) {
//		Enumeration keys = dic.keys();
//		while (keys.hasMoreElements()) {
//			Object key = keys.nextElement();
//			System.out.println(key + "=" + dic.get(key));
//		}
//	}
}
